package com.zto.sch.base.thread;

import org.junit.Test;

public class DeadLockDemo {

    /*
     * 此方法请求两个锁,第一个字符串,然后整数
     */
    public void method1() throws InterruptedException {
        for (int i = 0; i < 200; i++) {
            synchronized (String.class) {
                System.out.println("method1 String lock..." + Thread.currentThread().getName() + "--------" + i);
                synchronized (Integer.class) {
                    System.out.println("method1 Integer lock..." + Thread.currentThread().getName());
                }
            }
        }
        System.out.println("method1 over......" + Thread.currentThread().getName());
    }


    /*
     * 此方法也请求相同的两个锁,但完全
     * 相反的顺序,即首先整数,然后字符串。
     * 如果一个线程持有字符串锁,则这会产生潜在的死锁
     * 和其他持有整数锁,他们等待对方,永远。
     */
    public void method2() throws InterruptedException {
        for (int i = 0; i < 20; i++) {
            synchronized (Integer.class) {
                System.out.println("method2 Integer lock..." + Thread.currentThread().getName());

                synchronized (String.class) {
                    System.out.println("method2 String lock..." + Thread.currentThread().getName());
                }
            }
        }

        System.out.println("method2 over......" + Thread.currentThread().getName());


    }

    @Test
    public void testdeadLock() throws InterruptedException {
        DeadLockDemo deadLockDemo = new DeadLockDemo();
        Thread t1 = new Thread(() -> {
            try {
                deadLockDemo.method1();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t1");

        Thread t2 = new Thread(() -> {
            try {
                deadLockDemo.method2();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();


        System.out.println("main over-----------" + Thread.currentThread().getName());

    }
}